﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.Domain;
using Happy.Activities.Domain.WorkflowInstances;
using Happy.Activities.Domain.Workflows.Internal;

namespace Happy.Activities.Domain.Workflows
{
    /// <summary>
    /// 代表了流程中的一条路由。
    /// </summary>
    public class Router : Entity<Guid>
    {
        private IRouterCondition _condition;

        /// <summary>
        /// 显示名称
        /// </summary>
        public string DisplayName { get; set; }

        /// <summary>
        /// 源活动标识。
        /// </summary>
        public Guid FromId { get; set; }

        /// <summary>
        /// 目标活动标识。
        /// </summary>
        public Guid ToId { get; set; }

        /// <summary>
        /// 序列化后的条件类型。
        /// </summary>
        internal string SerializedConditionType { get; set; }

        /// <summary>
        /// 序列化后的条件内容。
        /// </summary>
        internal string SerializedConditionContent { get; set; }

        /// <summary>
        /// 设置路由条件。
        /// </summary>
        public void SetCondition(IRouterCondition condition)
        {
            _condition = condition;
            this.SerializedConditionType = condition.GetType().FullName;
            this.SerializedConditionContent = condition.SerializedToString();
        }

        /// <summary>
        /// 返回路由条件。
        /// </summary>
        public IRouterCondition GetCondition()
        {
            if (_condition == null)
            {
                if (string.IsNullOrEmpty(this.SerializedConditionType))
                {
                    _condition = new TrueRouterCondition();
                }
                else
                {
                    var conditionType = Type.GetType(this.SerializedConditionType);
                    _condition = Activator.CreateInstance(conditionType, this.SerializedConditionContent) as IRouterCondition;
                }
            }

            return _condition;
        }

        /// <summary>
        /// 所在流程标识。
        /// </summary>
        public Guid WorkflowId { get; internal set; }

        internal void Route(WorkflowContext context, ActivityInstance fromActivityInstance)
        {
            var fromActivity = context
                .WorkflowInstance
                .Workflow
                .Activities
                .First(x => x.Id == this.FromId);
            var toActivity = context
                .WorkflowInstance
                .Workflow
                .Activities
                .First(x => x.Id == this.ToId);

            var routerSplitToken = fromActivity.CreateRouterSplitToken(context, fromActivityInstance);
            var toActivityInstance = toActivity.CreateInstance(context, routerSplitToken);
            context.WorkflowInstance.AddActivityInstance(toActivityInstance);

            var routerInstance = new RouterInstance
            {
                FromInstanceId = fromActivityInstance.Id,
                Id = Guid.NewGuid(),
                RouterId = this.Id,
                SplitToken = String.Empty,
                ToInstanceId = toActivityInstance.Id,
                WorkflowInstanceId = context.WorkflowInstance.Id
            };
            context.WorkflowInstance.AddRouterInstance(routerInstance);

            toActivity.Enter(context, toActivityInstance);
        }
    }
}
